package com.hinotoyk.testsystem.uitls;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.List;

/* 学生答案JSON
 * {
 *      "sg":{
 *          "answer":["", "", ""],
 *          "score": 题型得分
 *      },
 *      "pl":{
 *          "answer":["", "", ""],
 *          "score": 题型得分
 *      },
 *      "tof":{
 *          "answer":["", "", ""],
 *          "score": 题型得分
 *      },
 *      "fill":{
 *          "answer":["", "", ""],
 *          "score": 题型得分
 *      },
 *      "essay":{
 *          "answer":["", "", ""],
 *          "score": 题型得分
 *      }
 *
 * }
 */
public class StudentAnswerJson {
    private List<String> sgAnswers = new ArrayList<>();
    private List<String> plAnswers = new ArrayList<>();
    private List<String> tofAnswers = new ArrayList<>();
    private List<String> fillAnswers = new ArrayList<>();
    private List<String> essayAnswers = new ArrayList<>();

    private int totalScore = 0;
    private int sgScore = 0;
    private int plScore = 0;
    private int tofScore = 0;
    private int fillScore = 0;
    private int essayScore = 0;

    public void ReCalculateTotalScore(){
        totalScore = sgScore + plScore + tofScore + essayScore + fillScore;
    }

    public int getTotalScore() {
        return totalScore;
    }

    public void setTotalScore(int totalScore) {
        this.totalScore = totalScore;
    }

    public void setScoreByType(int type, int score){
        if(type == QuestionType.SGQuestion.getType()){
            setSgScore(score);
        }else if(type == QuestionType.FillingQuestion.getType()){
            setFillScore(score);
        }else if(type == QuestionType.EssayQuestion.getType()){
            setEssayScore(score);
        }else if(type == QuestionType.PLQuestion.getType()){
            setPlScore(score);
        }else if(type == QuestionType.TOFQuestion.getType()){
            setTofScore(score);
        }
    }

    public int getSgScore() {
        return sgScore;
    }

    public void setSgScore(int sgScore) {
        this.sgScore = sgScore;
    }

    public int getPlScore() {
        return plScore;
    }

    public void setPlScore(int plScore) {
        this.plScore = plScore;
    }

    public int getTofScore() {
        return tofScore;
    }

    public void setTofScore(int tofScore) {
        this.tofScore = tofScore;
    }

    public int getFillScore() {
        return fillScore;
    }

    public void setFillScore(int fillScore) {
        this.fillScore = fillScore;
    }

    public int getEssayScore() {
        return essayScore;
    }

    public void setEssayScore(int essayScore) {
        this.essayScore = essayScore;
    }

    public List<String> getSgAnswers() {
        return sgAnswers;
    }

    public void setSgAnswers(List<String> sgAnswers) {
        this.sgAnswers = sgAnswers;
    }

    public List<String> getPlAnswers() {
        return plAnswers;
    }

    public void setPlAnswers(List<String> plAnswers) {
        this.plAnswers = plAnswers;
    }

    public List<String> getTofAnswers() {
        return tofAnswers;
    }

    public void setTofAnswers(List<String> tofAnswers) {
        this.tofAnswers = tofAnswers;
    }

    public List<String> getFillAnswers() {
        return fillAnswers;
    }

    public void setFillAnswers(List<String> fillAnswers) {
        this.fillAnswers = fillAnswers;
    }

    public List<String> getEssayAnswers() {
        return essayAnswers;
    }

    public void setEssayAnswers(List<String> essayAnswers) {
        this.essayAnswers = essayAnswers;
    }

    public static StudentAnswerJson MakeAndGetScore(TestPagerJson paper, QueryMap answerMap){
        StudentAnswerJson json = new StudentAnswerJson();
        List<String> [] lists = new List[QuestionType.TypeNames.length];
        lists[QuestionType.ErrorQuestion.getType()] = null;
        lists[QuestionType.SGQuestion.getType()] = json.getSgAnswers();
        lists[QuestionType.PLQuestion.getType()] = json.getPlAnswers();
        lists[QuestionType.TOFQuestion.getType()] = json.getTofAnswers();
        lists[QuestionType.FillingQuestion.getType()] = json.getFillAnswers();
        lists[QuestionType.EssayQuestion.getType()] = json.getEssayAnswers();

        for(int type = 1; type < lists.length; ++type){
            int score = 0;

            List<Integer> idList = paper.getListByQuestionType(type);
            if(idList == null) continue;

            int correctScore = paper.getScoreByQuestionType(type);

            for(int j = 0; j < idList.size(); ++j){
                String str = answerMap.getParameterValuesString(QuestionType.TypeNames[type]+"_"+idList.get(j));
                if(str == null)
                    str = "";

                lists[type].add(str);

                String correctAnswer = paper.getSave().getAnswerById(type, idList.get(j));

                if(correctAnswer != null){
                    // 如果是简答题，则进行不一样的判断
                    if(type == QuestionType.EssayQuestion.getType()){
                        double like = LevenshteinDistance.SIM(str, correctAnswer);
                        score += (like > 0.4)? (int)like * correctScore : 0;
                    }else {
                        score += correctScore * (str.equals(correctAnswer) ? 1 : 0);
                    }
                }
            }

            json.setScoreByType(type, score);
        }

        json.ReCalculateTotalScore();

        return json;
    }

    public static StudentAnswerJson MakeByJSONString(String str){
        StudentAnswerJson json = new StudentAnswerJson();
        JSONObject parser = JSON.parseObject(str);

        json.setTotalScore(parser.getIntValue("score"));

        JSONObject helper = parser.getJSONObject("sg");
        json.setSgAnswers(helper.getJSONArray("answer").toJavaList(String.class));
        json.setSgScore(helper.getIntValue("score"));

        helper = parser.getJSONObject("pl");
        json.setPlAnswers(helper.getJSONArray("answer").toJavaList(String.class));
        json.setPlScore(helper.getIntValue("score"));

        helper = parser.getJSONObject("tof");
        json.setTofAnswers(helper.getJSONArray("answer").toJavaList(String.class));
        json.setTofScore(helper.getIntValue("score"));

        helper = parser.getJSONObject("fill");
        json.setFillAnswers(helper.getJSONArray("answer").toJavaList(String.class));
        json.setFillScore(helper.getIntValue("score"));

        helper = parser.getJSONObject("essay");
        json.setEssayAnswers(helper.getJSONArray("answer").toJavaList(String.class));
        json.setEssayScore(helper.getIntValue("score"));

        return json;
    }
    static JSONObject MakeAnswerJsonObject(List<String> list, int score){
        JSONObject obj = new JSONObject();
        JSONArray array = new JSONArray();

        for(int i = 0; i < list.size(); ++i)
            array.add(i, list.get(i));
        obj.put("answer", array);
        obj.put("score", score);
        return obj;
    }

    JSONObject toJSONObject(){
        JSONObject obj = new JSONObject();
        obj.put("score", totalScore);
        obj.put("sg", MakeAnswerJsonObject(sgAnswers, sgScore));
        obj.put("pl", MakeAnswerJsonObject(plAnswers, plScore));
        obj.put("fill", MakeAnswerJsonObject(fillAnswers, fillScore));
        obj.put("tof", MakeAnswerJsonObject(tofAnswers, tofScore));
        obj.put("essay", MakeAnswerJsonObject(essayAnswers, essayScore));
        return obj;
    }

    public String toJSONString(){
        return toJSONObject().toJSONString();
    }

    @Override
    public String toString() {
        return toJSONString();
    }
}
